
import os
import xml.etree.ElementTree as ET
from docx import Document
from docx.shared import Cm
import datetime


# 解析cppcheck工具生成的xml结果
def parse_xml_result(xml_path):
    tree = ET.parse(xml_path)
    root = tree.getroot()
    check_date = root.attrib.get('version')
    errors = root.findall('.//error')
    check_result = {"error": [], "warning": [], "style": [], "performance": [], "portability": [], "information": []}

    # info_lst = [[],[],[],[],[],[]]
    for issue in errors:

        id = issue.attrib.get('id')
        message = issue.attrib.get('msg')
        severity = issue.attrib.get('severity')

        if id == "missingInclude":
            info_str = f"{severity.upper()} - **{message}**  \n"
        elif id == "syntaxError":
            continue
        elif id == "internalAstError":
            continue
        else:
            sub_element = issue.find('location')
            file = sub_element.attrib.get('file')
            line = sub_element.attrib.get('line')
            column = sub_element.attrib.get('column')
            info_str = f"{severity.upper()} - **{message}**  \n\nFILE: `{file}`,\nLINE: `{line}`, COLUMN: `{column}`\n"

        # 将警告信息转换为文本格式
        print(info_str)
        check_result[severity].append(info_str)

    return check_date, check_result



def make_report_table_in_docx(document, err_level_str:str, info_lst):
    document.add_heading(f'Type of {err_level_str.lower()}: ', 2)
    # 创建表格
    table = document.add_table(rows=len(info_lst) + 1, cols=2)
    # 设置表格样式
    table.style = 'Table Grid'
    # 设置表格宽度
    table.autofit = True
    # for cell in table.columns[0].cells:
    #     cell.width = Cm(2)
    # for cell in table.columns[1].cells:
    #     cell.width = Cm(13)

    # 插入表头
    hdr_cells = table.rows[0].cells
    hdr_cells[0].text = '序号'
    hdr_cells[1].text = '具体信息'

    idx = 1
    for info in info_lst:
        print(f"***** {idx} / {len(info_lst)} *****")
        hdr_cells = table.rows[idx].cells
        hdr_cells[0].text = idx.__str__()
        hdr_cells[1].text = info
        idx += 1



# 创建word文档并插入检查结果表格
def create_report(doc_path, check_date, check_result):
    document = Document()
    # 设置文档标题
    document.add_heading('Cppcheck检查报告', 0)
    # 设置检查日期
    document.add_paragraph(f'检查日期：{check_date}')
    # 创建表格
    table = document.add_table(rows=7, cols=2)
    # 设置表格样式
    table.style = 'Table Grid'
    # 设置表格宽度
    table.autofit = False
    table.width = Cm(15)
    # 插入表头
    hdr_cells = table.rows[0].cells
    hdr_cells[0].text = '缺陷等级'
    hdr_cells[1].text = '缺陷数量'
    # 插入检查结果
    row_cells = table.rows[1].cells
    row_cells[0].text = 'error（错误）'
    row_cells[1].text = str(len(check_result['error']))

    row_cells = table.rows[2].cells
    row_cells[0].text = 'warning（警告）'
    row_cells[1].text = str(len(check_result['warning']))

    row_cells = table.rows[3].cells
    row_cells[0].text = 'style（风格）'
    row_cells[1].text = str(len(check_result['style']))

    row_cells = table.rows[4].cells
    row_cells[0].text = 'performance（性能）'
    row_cells[1].text = str(len(check_result['performance']))

    row_cells = table.rows[5].cells
    row_cells[0].text = 'portability（可移植性）'
    row_cells[1].text = str(len(check_result['portability']))

    row_cells = table.rows[6].cells
    row_cells[0].text = 'information（信息）'
    num = len(check_result['information'])
    row_cells[1].text = num.__str__()

    # 输出详细信息
    document.add_heading('详细信息', 1)

    type_tag = "error"
    make_report_table_in_docx(document, type_tag, check_result[type_tag])
    type_tag = "warning"
    make_report_table_in_docx(document, type_tag, check_result[type_tag])
    type_tag = "style"
    make_report_table_in_docx(document, type_tag, check_result[type_tag])
    type_tag = "performance"
    make_report_table_in_docx(document, type_tag, check_result[type_tag])
    type_tag = "portability"
    make_report_table_in_docx(document, type_tag, check_result[type_tag])
    type_tag = "information"
    make_report_table_in_docx(document, type_tag, check_result[type_tag])


    # 保存报告
    document.save(doc_path)





# 使用示例
if __name__ == '__main__':
    import sys

    argv = sys.argv
    now = datetime.datetime.now()
    now_str = now.strftime("%Y年%m月%d日")
    print("当前日期为：", now_str)

    xml_path = 'cppcheck_report.xml'
    doc_path = 'cppcheck_report.docx'
    # xml_path = argv[1]
    # doc_path = argv[2]
    check_date, check_result = parse_xml_result(xml_path)
    create_report(doc_path, now_str, check_result)
    
    